<?php
/**
 * Created by PhpStorm.
 * User: yangh
 * Date: 2017/8/5
 * Time: 9:22
 */

namespace app\api\service;

use think\Exception;
use app\lib\exception\WeChatException;
use app\lib\exception\TokenException;
use app\api\model\User as UserModel;


class UserToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'),$this->wxAppID,$this->wxAppSecret,$this->code);
    }

    public function get(){
        $result = curl_get($this->wxLoginUrl);
        $wxResult = json_decode($result,true);
        if (empty($wxResult)){
            throw new Exception('获取session_key及openid时异常，微信内部错误');
        }else{
            $loginFail = array_key_exists('errcode',$wxResult);
            if ($loginFail){
                $this->processLoginError($wxResult);
            }else{
                return $this->grantToken($wxResult);
            }
        }
    }

    private function grantToken($wxResult){
        //难道oppenid
        //数据库里看一下这个oppenid是否已存在
        //若存在不处理，若不存在新增记录
        //准备缓存数据写入缓存
        //把令牌返回到客户端去
        //key:令牌
        //value：wxResult,uid,scope
        $openid = $wxResult['openid'];
        $user = UserModel::getByOpenID($openid);
        $register = null;
        if($user){
            $user_id = $user->user_id;
        }else{
            $user_id = $this->newUser($openid);
        }
        $cachedValue = $this->prepareCachedValue($wxResult,$user_id);
        $token = $this->saveToCache($cachedValue);
        return [
            'token' => $token,
        ];
    }

    private function saveToCache($cachedValue){
        $key = self::generateToken();
        $value = json_encode($cachedValue);
        $expire_in = config('setting.token_expire_in');
        $request = cache($key,$value,$expire_in);
        if (!$request){
            throw new TokenException([
                'msg' =>'服务器异常',
                'errorCode' => 10005
            ]);
        }
        return $key;
    }

    private function prepareCachedValue($wxResult,$user_id){
        $cachedValue = $wxResult;
        $cachedValue['user_id'] = $user_id;
        $cachedValue['scope'] = 16;
        return $cachedValue;

    }

    public function newUser($openid){
        $user = UserModel::create([
           'user_openid' => $openid,
        ]);
        return $user->user_id;
    }

    private function processLoginError($wxResult){
        throw new WeChatException([
            'msg'  => $wxResult['errmsg'],
            'errorCode' => $wxResult['errcode']
        ]);
    }
}